/* Copyright 2010 Hugh Greenberg */   

package com.hugegreenbug.msoss;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.xml.sax.Attributes;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

public class ImageFinderHandler extends DefaultHandler {
	private boolean mGotClass;
	private boolean mSorted;
	private String mLink;
	private int mWidth;
	private int mHeight;
	private float mCanvasRatio;
	private int mMaxThumbs = 50;
	private int mCurThumbs;
	private boolean mMusician;
	private boolean mGotCats;
	private ArrayList<WikiCommonsThumb> mThumbs;

	public ImageFinderHandler(float canvasRatio) {
		super();
		mCanvasRatio = canvasRatio;
		if (canvasRatio > 0)
			mSorted = true;
		else
			mSorted = false;
	}
	
	@Override
	public void startDocument() {
		mThumbs = new ArrayList<WikiCommonsThumb>();
		mGotClass = false;
		mLink = null;
		mWidth = 0;
		mHeight = 0;
		mCurThumbs = 0;
		mMusician = false;
		mGotCats = false;	
	}
	
	@Override
	public void endDocument() {
	}
	
    @Override
	public void startElement (String uri, String name, String qName, Attributes atts) {
    	if (!name.equals("div") && !name.equals("a") && !name.equals("img"))
    		return;
    	
    	for (int i = 0; i < atts.getLength(); i++) {
			String attrName = atts.getQName(i);
			String value = atts.getValue(i);
		
			if (!mGotClass && attrName.equals("class") && value.equals("thumb")) {
				mGotClass = true;
				return;
			} 
			
			if (mGotClass && attrName.equals("href") && name.equals("a")) {
				mLink = (Ms.msEngine.WIKI_COMMONS_BASE + value).replace(' ', '_');
				Pattern pat = Pattern.compile("http");
				Matcher mat = pat.matcher(mLink);
				if (!mat.find()) {
					mWidth = mHeight = 0;
					mGotClass = false;
					mLink = null;
				}
			}
			
			if (mLink != null && name.equals("img") && attrName.equals("width")) {
				try {
					mWidth = Integer.parseInt(value);
				} catch (NumberFormatException nfe) {
					mWidth = mHeight = 0;
					mGotClass = false;
					mLink = null;
				}
			}
			
			if (mLink != null && name.equals("img") && attrName.equals("height")) {
				try {
					mHeight = Integer.parseInt(value);
				} catch (NumberFormatException nfe) {
					mWidth = mHeight = 0;
					mGotClass = false;
					mLink = null;
				}
			}
			
			if (!mMusician && !mGotCats && name.equals("div") && attrName.equals("class")) {
				if (value.equals("catlinks")) {
					mGotCats = true;
					mWidth = mHeight = 0;
					mGotClass = false;
					mLink = null;
				}	
			}
			
			if (!mMusician && mGotCats && name.equals("a") && attrName.equals("title")) {
				Pattern pat = Pattern.compile(".*Music.*", Pattern.CASE_INSENSITIVE);
				Matcher mat = pat.matcher(value);
				if (mat.find()) {
					mMusician = true;
					continue;
				}
				
				pat = Pattern.compile(".*Singer.*", Pattern.CASE_INSENSITIVE);
				mat = pat.matcher(value);
				if (mat.find()) 
					mMusician = true;
			}
		}
    	
    	if (mGotClass && mLink != null && mWidth != 0 && mHeight != 0 && mCurThumbs < mMaxThumbs) {
    		WikiCommonsThumb thumb = new WikiCommonsThumb(mLink, mWidth, mHeight);
    		mThumbs.add(thumb);
    		mCurThumbs++;
    		if (mCanvasRatio > 0)
    			sortList();
    		
    		mGotClass = false;
    		mLink = null;
    		mWidth = mHeight = 0;
    	}
    }

    @Override
	public void endElement (String uri, String name, String qName) {
  
    }
    
    @Override
	public void error (SAXParseException e) {
    }
    
    @Override
	public void fatalError (SAXParseException e) {
    }
    
    @Override
	public void warning (SAXParseException e) {
    }
    
    public ArrayList<WikiCommonsThumb> getThumbs() {
    	return mThumbs;
    }
    
    public boolean isMusician() {
    	return mMusician;
    }
    
    public boolean isSorted() {
    	return mSorted;
    }
    
    public void sortList() {    	
    	for (int i = 1; i < mThumbs.size(); i++) {
    		int j = i - 1;
    		WikiCommonsThumb thumb1 = mThumbs.get(i);
    		float thumb1Diff = Math.abs(mCanvasRatio - thumb1.getRatio());
    		boolean done = false;
    		while (!done) {    			
    			WikiCommonsThumb thumb2 = mThumbs.get(j);
    			float thumb2Diff = Math.abs(mCanvasRatio - thumb2.getRatio());    	
    			if (thumb1Diff < thumb2Diff) {
    				mThumbs.set(j+1, thumb2);
    				j -= 1;
    				if (j < 0)
    					done = true;
    			} else
    				done = true;
    		
    			if (done)
    				break;
    			
    		}
    		
    		mThumbs.set(j+1, thumb1);
    	}
    }
       
}